/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package entities;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

/**
 *
 * @author Alberto, Alessandra
 */
@Entity
@Table(
        uniqueConstraints =
            @UniqueConstraint(columnNames = {"username"})
)
@NamedQueries({
    @NamedQuery(
            name = "findByUsername",
            query = "SELECT u FROM User u WHERE u.username = :Uusername"
    ),
    @NamedQuery(
            name = "searchByUsername",
            query = "SELECT u FROM User u WHERE u.username LIKE :Uusername"
    )
})
public class User implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
   
    @NotNull(message = "May not be empty")
    private String username;
    
    @NotNull(message = "May not be empty")
    private String name;
    
    @NotNull(message = "May not be empty")
    private String surname;
    
    @Pattern(regexp = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
            message = "invalid email")
    @NotNull(message = "May not be empty")
    private String email;
    
    @NotNull(message = "May not be empty")
    private String password;
    
    @NotNull(message = "May not be empty")
    private  Boolean calendarvisibility;
    
    @NotNull(message = "May not be empty")
    private String groupName;
    
    private String address;
    
    private String telnumber;
    
    @OneToMany(mappedBy = "creator")
    private Collection<Event> createdevents;
    
    @OneToMany(mappedBy = "user")
    private Collection<Notification> notifications;
    
    @OneToMany(mappedBy = "user")
    private Collection<Invitation> invitations;
    
    @ManyToMany
    @JoinTable(
            name = "Participation",
            joinColumns = 
                     @JoinColumn(name = "iduser", referencedColumnName = "id"),
            inverseJoinColumns = 
                     @JoinColumn(name = "idevent", referencedColumnName = "id")
    )
    private Collection<Event> events;

    public Collection<Event> getCreatedevents() {
        return createdevents;
    }
    
    public User () {
        this.createdevents = new ArrayList<>();
        this.invitations = new ArrayList<>();
        this.notifications = new ArrayList<>();
        this.events = new ArrayList<>();
    }

    public void setCreatedevents(Collection<Event> createdevents) {
        this.createdevents = createdevents;
    }

    public Collection<Notification> getNotifications() {
        return notifications;
    }

    public void setNotifications(Collection<Notification> notifications) {
        this.notifications = notifications;
    }

    public Collection<Invitation> getInvitations() {
        return invitations;
    }

    public void setInvitations(Collection<Invitation> invitations) {
        this.invitations = invitations;
    }

    public Collection<Event> getEvents() {
        return events;
    }

    public void setEvents(Collection<Event> events) {
        this.events = events;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(password.getBytes("UTF-8"));
            BigInteger bigInt = new BigInteger(1, hash);
            this.password = bigInt.toString(16);
//            StringBuilder hexString = new StringBuilder();
//            for (int i = 0; i < hash.length; i++) {
//                hexString.append(Integer.toHexString(0xFF & hash[i]));
//            }
//            this.password = hexString.toString();
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
            Logger.getLogger(User.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public Boolean getCalendarvisibility() {
        return calendarvisibility;
    }

    public void setCalendarvisibility(Boolean calendarvisibility) {
        this.calendarvisibility = calendarvisibility;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getTelnumber() {
        return telnumber;
    }

    public void setTelnumber(String telnumber) {
        this.telnumber = telnumber;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    
    public void addEvent (Event event) {
        this.events.add(event);
    }
    
    public void removeEvent (Event event) {
        this.events.remove(event);
    }
    
    public void addCreatedEvent (Event event) {
        this.createdevents.add(event);
    }
    
    public void removeCreatedEvent (Event event) {
        this.createdevents.remove(event);
    }
    
    public void addInvitation (Invitation invitation) {
        this.invitations.add(invitation);
    }
    
    public void removeInvitation (Invitation invitation) {
        this.invitations.remove(invitation);
    }
    
    public void addNotification (Notification notification) {
        this.notifications.add(notification);
    }
    
    public void removeNotification (Notification notification) {
        this.notifications.remove(notification);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final User other = (User) obj;
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        return true;
    }
    
    
}
